﻿using System;
using System.Linq;

namespace 历史积累
{
    /// <summary>
    /// 降噪类
    /// </summary>
    public class Denoise : DisposableBase
    {
        /// <summary>
        /// 存储数据
        /// </summary>
        private double[] Data { get; set; }

        /// <summary>
        /// 存储长度
        /// </summary>
        public int Len { get; }

        /// <summary>
        /// 数据长度
        /// </summary>
        public int Count { get; private set; }

        /// <summary>
        /// 当前位置
        /// </summary>
        private int Index { get; set; }

        /// <summary>
        /// 跳过数量
        /// </summary>
        private int Skip { get; }

        /// <summary>
        /// 获取数量
        /// </summary>
        private int Take { get; }

        public Denoise(int len = 3)
        {
            if (len < 3) len = 3;
            Len = len;
            Skip = Len / 3;
            Take = Len - (Skip * 2);
            Data = new double[len];
        }

        public void Init()
        {
            lock (Data)
            {
                Index = 0;
                Array.Clear(Data, 0, Len);
            }
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="value"></param>

        public void Add(double value)
        {
            lock (Data)
            {
                Value = null;
                Data[Index] = value;//循环存储数据
                if (Len > Count) Count++;//记录实际长度
                if (++Index >= Len) Index = 0;
            }
        }

        /// <summary>
        ///记录Value 避免多次Get 重复计算
        /// </summary>
        private double? Value { get; set; }

        /// <summary>
        /// 获取降噪数值
        /// </summary>
        /// <returns></returns>
        public double GetValue()
        {
            lock (Data)
            {
                if (Count > 0)
                {
                    if (Count == Len)//存储够了
                    {
                        // 先排序 跳过1/3 然后再不要 后面 1/3  拿中间 的数的平均值
                        return Value ?? Data.OrderBy(a => a).Skip(Skip).Take(Take).Average();
                    }//储存长度不够   取实际存储数据平均值
                    else return Data.Take(Count).Average();
                }//实际长度为0 没有数据返回 0
                else return 0;
            }
        }

        protected override void OnDispose()
        {
            Data = null;
        }
    }
}